package com.acme.mock;


import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.BindException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;

import com.acme.bankapp.domain.bank.Bank;
import com.acme.bankapp.exceptions.FeedLoaderException;
import com.acme.bankapp.service.bank.BankDataLoaderService;
import com.acme.bankapp.service.bank.BankService;

public class BankServer {
	ServerSocket providerSocket;
	Socket connection = null;
	ObjectOutputStream out;
	ObjectInputStream in;
	String message;

	public BankServer() {
	}

	public void run(Bank bank) throws FeedLoaderException {
		try {
			// 1. creating a server socket
			providerSocket = new ServerSocket(2004, 10);
			// 2. Wait for connection
			System.out.println("Waiting for connection");
			connection = providerSocket.accept();
			System.out.println("Connection received from "
					+ connection.getInetAddress().getHostName());
			// 3. get Input and Output streams
			out = new ObjectOutputStream(connection.getOutputStream());
			out.flush();
			in = new ObjectInputStream(connection.getInputStream());
			sendMessage("Connection successful");
			// 4. The two parts communicate via the input and output streams
			do {
				try {
					message = (String) in.readObject();
					System.out.println("client>" + message);
					String command[] = message.split(" ",2);
					switch (command[0]) {
					case "add":
						if (command.length == 2){
							if (BankService.addClient(bank, BankDataLoaderService.getClientFromString( command[1] ) ) ){
								sendMessage("Client added");
							}else{
								System.out.println("incorrect parameters or client already exists"); 
							}
						} else {
							sendMessage("unknown command");
						}
						break;
					case "getClients":
						sendMessage( BankReport.getCliensList(bank) );
						break;
					case "bye":
						sendMessage("bye");
						break;
					default:
						sendMessage("unknown command");
						sendMessage("bye");
						break;
					} 
				} catch (ClassNotFoundException classnot) {
					System.err.println("Data received in unknown format");
				} catch (FeedLoaderException feedExc){
					sendMessage(feedExc.getLocalizedMessage());
				} catch (SocketException socExc){
					System.out.println(socExc.getMessage());
				}
				
			} while (!message.equals("bye"));
		} catch (BindException bindExc) {
			System.out.println(bindExc.getMessage());
		} catch (IOException ioException) {
			ioException.printStackTrace();
		} finally {
			// 4: Closing connection
			try {
				in.close();
				out.close();
				providerSocket.close();
			} catch (IOException ioException) {
				ioException.printStackTrace();
			}
		}
	}

	void sendMessage(final String msg) {
		try {
			out.writeObject(msg);
			out.flush();
			System.out.println("server>" + msg);
		} catch (IOException ioException) {
			ioException.printStackTrace();
		}
	}
}
